/**
 *
 */
package com.engine.Mangers;

import java.util.Date;
import java.util.List;

import org.hibernate.Session;

import com.util.EngineUtil;
import com.wfe.db.SessionUtil;
import com.wfe.db.WorkFlowEngineQueryUtil;
import com.wfe.mapping.client.WfProject;
import com.wfe.mapping.client.WfProjectStatus;
import com.wfe.mapping.client.WfProjectTask;
import com.wfe.mapping.client.WfProjectTaskStatus;
import com.wfe.mapping.client.WfTaskType;

/**
 * @author kareem_yehya
 * @since 16 04 2009<br>
 *        <H2>This thread responsible for Close project which reached the End Task * @version 1.0.0.1
 */
public class EndProjects implements Runnable
{

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run()
	{

		while(true)
		{
			try
			{
				// ------------------------- assigned process tasks
				System.out.println("Inside End Projects main Thread");
				List<WfProjectTask> taskList = loadAssignedEndTasks(500);
				if(taskList.size() > 0)
				{
					for(WfProjectTask projectTask : taskList)
					{
						boolean isclosed = updateTask(projectTask);
						if(isclosed)
						{
							updateProject(projectTask);
							CloseNonExecutedTasks(projectTask);

						}

					}

				}
				Thread.sleep(500);
			}catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	private List<WfProjectTask> loadAssignedEndTasks(int maxresults)
	{
		Session session = null;
		try
		{

			// ------------------------ get process tasks
			WfTaskType taskType = getwfTaskTypeByTypeID(6); // End
			WfProjectTaskStatus taskStatus = getWfProjectTaskStatusByID(4); // assigned
			WfProjectStatus projectStatus = getWfProjectStatusByID(2); // inprocess
			session = SessionUtil.getSession();
			List<WfProjectTask> tasklist = WorkFlowEngineQueryUtil.getProjectTasks(session, projectStatus, maxresults, taskType, taskStatus, false);

			return tasklist;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	public WfTaskType getwfTaskTypeByTypeID(long tasktype)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WfTaskType taskType = WorkFlowEngineQueryUtil.getWfTaskType(session, tasktype);

			return taskType;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		(new Thread(new EndProjects())).start();

	}

	/**
	 * @author kareem_yehya
	 * @since 04 April 2009 <br>
	 *        Call this method to return WfProjectStatus
	 * 
	 * @return WfProjectStatus
	 * */

	public WfProjectStatus getWfProjectStatus(long statusID)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WfProjectStatus projectStatus = WorkFlowEngineQueryUtil.getwfProjectStatusByID(statusID, session);

			return projectStatus;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	private boolean updateProject(WfProjectTask projectTask)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WfProject orginalProject = projectTask.getWfProject();
			WfProject project = WorkFlowEngineQueryUtil.getWfProjectByID(orginalProject.getRecid(), session);
			project.setFinishTime(new Date());
			project.setWfProjectStatus(getWfProjectStatusByID(3l)); // completed
			WorkFlowEngineQueryUtil.updateWfProject(project, session);

			return true;
		}catch(Exception e)
		{
			e.printStackTrace();
			return false;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	private boolean updateTask(WfProjectTask projectTask)
	{
		Session session = null;
		try
		{
			projectTask.setWfProjectTaskStatus(getWfProjectTaskStatusByID(1l)); // success
			projectTask.setStartTime(new Date());
			projectTask.setUserId(0l);
			projectTask.setGroupId(0l);
			projectTask.setEndTime(new Date());
			projectTask.setIsProcessed(true);
			// -------- update Task
			// Session session = SessionUtil.getCurrentSession();
			session = SessionUtil.getSession();
			WorkFlowEngineQueryUtil.updateWfProjectTask(projectTask, session);

			// ----------Route Task
			// Router.route(projectTask);
			return true;
		}catch(Exception e)
		{
			e.printStackTrace();
			return false;
		}finally
		{

			EngineUtil.closeSession(session);

		}

	}

	private WfProjectTaskStatus getWfProjectTaskStatusByID(long i)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WfProjectTaskStatus projectTaskStatus = WorkFlowEngineQueryUtil.getWfProjectTaskStatusByID(i, session);

			return projectTaskStatus;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	private void CloseNonExecutedTasks(WfProjectTask projectTask)
	{

		WfProjectTask mainTask = getWfProjectTaskByID(projectTask.getRecid());
		WfProject mainProject = mainTask.getWfProject();

		java.util.List<WfProjectTask> allProjectTasks = getWfProjectTasks(mainProject);
		for(WfProjectTask task : allProjectTasks)
		{
			// if(task.getWfProjectTaskStatus().getRecid() == 5)// created
			if(task.getWfProjectTaskStatus().getRecid().longValue() == 5)// created
			{
				task.setUserId(0l);
				task.setGroupId(0l);
				task.setWfProjectTaskStatus(getWfProjectTaskStatusByID(6l));// unexecuted
				updateunexecutedTask(task);
			}
		}
	}

	private static List<WfProjectTask> getWfProjectTasks(WfProject project)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			List<WfProjectTask> retList = WorkFlowEngineQueryUtil.getWfProjectTasksByProject(project, session);

			return retList;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);

		}

	}

	private WfProjectStatus getWfProjectStatusByID(long i)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WfProjectStatus projectStatus = WorkFlowEngineQueryUtil.getwfProjectStatusByID(i, session);

			return projectStatus;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	private static WfProjectTask getWfProjectTaskByID(long taskID)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WfProjectTask projectTask = WorkFlowEngineQueryUtil.getWfProjectTaskByID(session, taskID);

			return projectTask;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	private static void updateunexecutedTask(WfProjectTask task)
	{
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WorkFlowEngineQueryUtil.updateWfProjectTask(task, session);
		}catch(Exception e)
		{
			e.printStackTrace();
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

}
